package com.xmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmall.define.base.ResultCode;
import com.xmall.define.constants.CommonConstants;
import com.xmall.define.dto.product.EsBaseAttrDto;
import com.xmall.exception.XmallException;
import com.xmall.product.define.dict.AttrOptionTypeEnum;
import com.xmall.product.define.dto.baseAttr.BaseAttrDo;
import com.xmall.product.define.dto.baseAttr.BaseAttrDto;
import com.xmall.product.define.request.attr.BaseAttrQueryParams;
import com.xmall.product.define.request.attr.BaseAttrUpdateRequest;
import com.xmall.product.entity.BaseAttr;
import com.xmall.product.mapper.BaseAttrMapper;
import com.xmall.product.service.IAttrOptionService;
import com.xmall.product.service.IBaseAttrService;
import com.xmall.product.utils.ConvertUtils;
import com.xmall.utils.XmallUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 属性 服务实现类
 * </p>
 *
 * @author xmall
 * @since 2023-11-02
 */
@Service
public class BaseAttrServiceImpl extends ServiceImpl<BaseAttrMapper, BaseAttr> implements IBaseAttrService {

    @Resource
    private IAttrOptionService attrOptionService;

    /**
     * 构造es基本属性对象
     */
    @Override
    public List<EsBaseAttrDto> buildEsBaseAttr(List<Long> attrIds) {
        return ConvertUtils.BaseAttrModule.INSTANCE.toEsList(this.listByIds(attrIds));
    }

    /**
     * 新增
     */
    @Transactional
    @Override
    public void saveEntity(BaseAttrUpdateRequest request) {
        checkRepeatAttrName(request.getGroupId(), request.getName());

        // 获取排序值
        Integer maxSort = this.baseMapper.getMaxSort(request.getGroupId());
        request.setSort(null == maxSort ? CommonConstants.DEFAULT_SORT_NUM : maxSort + 1);

        BaseAttr baseAttr = ConvertUtils.BaseAttrModule.INSTANCE.toEntity(request);
        this.save(baseAttr);

        attrOptionService.save(baseAttr.getId(), AttrOptionTypeEnum.BASE, request.getOptionList());
    }

    // 校验重复性（相同分组下的名称不能重复）
    private void checkRepeatAttrName(Long groupId, String attrName) {
        List<String> nameList = this.list(new QueryWrapper<BaseAttr>().eq("group_id", groupId)).stream().map(attr -> attr.getName()).collect(Collectors.toList());
        if(nameList.contains(attrName)) {
            throw new XmallException(ResultCode.PRODUCT_ATTR_NAME_REPEAT);
        }
    }

    /**
     * 编辑
     */
    @Transactional
    @Override
    public void updateEntity(BaseAttrUpdateRequest request) {
        BaseAttr entity = this.getById(request.getId());
        XmallUtils.notNull(entity);

        this.updateById(ConvertUtils.BaseAttrModule.INSTANCE.toEntity(request));

        attrOptionService.removeByAttrId(request.getId(), AttrOptionTypeEnum.BASE);
        attrOptionService.save(request.getId(), AttrOptionTypeEnum.BASE, request.getOptionList());
    }

    /**
     * 删除
     */
    @Transactional
    @Override
    public void deleteEntity(Long id) {
        this.removeById(id);
        attrOptionService.removeByAttrId(id, AttrOptionTypeEnum.BASE);
    }

    /**
     * 交换排序值
     */
    @Transactional
    @Override
    public void swapSort(Long prevAttrId, Long nextAttrId) {
        BaseAttr prevAttr = this.getById(prevAttrId);
        BaseAttr nextAttr = this.getById(nextAttrId);

        XmallUtils.notNull(prevAttr);
        XmallUtils.notNull(nextAttr);

        BaseAttr updatePrevAttr = new BaseAttr();
        updatePrevAttr.setId(prevAttrId);
        updatePrevAttr.setSort(nextAttr.getSort());
        this.updateById(updatePrevAttr);

        BaseAttr updateNextAttr = new BaseAttr();
        updateNextAttr.setId(nextAttrId);
        updateNextAttr.setSort(prevAttr.getSort());
        this.updateById(updateNextAttr);
    }

    /**
     * 属性列表
     */
    @Override
    public List<BaseAttrDto> listWithCascade(BaseAttrQueryParams params) {
        List<BaseAttrDo> list = this.baseMapper.listWithCascade(params);
        return ConvertUtils.BaseAttrModule.INSTANCE.doList2DtoList(list);
    }

    /**
     * 详情
     */
    @Override
    public BaseAttrDto infoWithCascade(Long id) {
        BaseAttrDo entity = this.baseMapper.infoWithCascade(id);
        XmallUtils.notNull(entity);
        return ConvertUtils.BaseAttrModule.INSTANCE.do2Dto(entity);
    }

}
